# 将图像转换为卡通风格：
# cell 1 import各库，输入图像，并且BGR2RGB
import numpy as np
import cv2
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread('face.jpg')
r,g,b=cv.split(img)
img=cv.merge([b,g,r])
plt.imshow(img)
plt.show()

# cell 2 创建边缘遮罩，转为灰度图，使用中置模糊、adaptiveThreshold提取高频边缘信息
def edge_mask(img, line_size, blur_value):
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  gray_blur = cv2.medianBlur(gray, blur_value)
  edges = cv2.adaptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, line_size, blur_value)
  return edges
edges=edge_mask(img,9,5)
plt.imshow(edges)

# cell 3 进行颜色量化，使用 KMeans 聚类算法
def color_quantization(img, k):
# 变换图形
  data = np.float32(img).reshape((-1, 3))
# 设定条件
  criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)
# K-Means 实现
  ret, label, center = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
  center = np.uint8(center)
  result = center[label.flatten()]
  result = result.reshape(img.shape)
  return result

# cell 4 调用颜色量化函数生成图像，设定k值确定颜色数量
total_color = 9 
img =color_quantization(img,total_color)
plt.imshow(img)

# cell 5 使用双边过滤器减少图像的噪点
# d —每个像素邻域的直径
# sigmaColor —参数的值越大，表示面积越大的半均等颜色。
# sigmaSpace –参数的值越大，表示越远的像素只要它们的颜色足够接近，就会相互影响。
blurry=cv2.bilateralFilter(img,d = 7,sigmaColor = 200,sigmaSpace = 200)
plt.imshow(blurry)

# cell 6 结合提取的边缘蒙版和经过颜色量化的图像
cartoon = cv2.bitwise_and(blurry,blurry,mask = edges)
plt.imshow(cartoon)

# 将原图转换为黑白线条风格：
# cell 1 
import cv2

img_rgb = cv2.imread("imge.jpg")
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)
img_blur = cv2.GaussianBlur(img_gray, ksize=(21, 21),
                            sigmaX=0, sigmaY=0)
tp=cv2.divide(img_gray, img_blur, scale=255)
cv2.imwrite("dis.jpg",tp)

# 将图像转换为路径中图像的指定颜色风格：
# Cell 1 安装scikit-image库
!pip install scikit-image

# Cell 2 import各库
import paddle
import paddle as P
from paddle import ParamAttr
import paddle.nn as nn
import paddle.nn.functional as F
from paddle.nn import Conv2D, BatchNorm, Linear, Dropout, AdaptiveAvgPool2D, MaxPool2D, AvgPool2D
import numpy as np
import PIL
# 使用sklearn机器学习库的KNN算法，节省编码时间
from sklearn.neighbors import KNeighborsRegressor
import os
# 改用skimage进行输入输出、颜色空间转换、几何变换
from skimage import io
from skimage.color import rgb2lab, lab2rgb
from skimage.transform import resize
import matplotlib.pyplot as plt
import math
# 分配GPU
place = P.CUDAPlace(0)
P.disable_static(place)

# cell 3 声明风格文件夹、改变风格的content图像
image_style = '/home/aistudio/work/style/'
image_content = '/home/aistudio/work/content/0001.jpg'
print('风格图像：')
plt.imshow(io.imread(image_style+'0001.jpg'))
plt.show()
print('内容图像：')
plt.imshow(io.imread(image_content))
plt.show()
# KNN选取的边框
edge_size = 1
k = 4

# cell 4 生成数据集函数（将图像转为 Lab 颜色通道，提取色彩风格）
def create_dataset(image):
    img = rgb2lab(io.imread(image))
    row, col = img.shape[0:2]
    L = []
    ab = []
    for x in range(edge_size, row-edge_size):
        for y in range(edge_size, col-edge_size):
            L.append(img[x-edge_size : x+edge_size+1, y-edge_size : y+edge_size+1, 0].reshape([-1]))
            ab.append(img[x, y, 1:2+1])
    return L, ab, row, col

# cell 5 使用机器学习库训练
L_train = []
ab_train = []
for file in os.listdir(image_style):
    L0, ab0, _, _ = create_dataset(image_style+file)
    L_train.extend(L0)
    ab_train.extend(ab0)

knnr = KNeighborsRegressor(n_neighbors=k, weights='distance')
knnr.fit(L_train, ab_train)

# cell 6重建风格迁移后的图像
def rebuild(image_content):
    L, _, row, col = create_dataset(image_content)
    ab = knnr.predict(L).reshape([row-2*edge_size, col-2*edge_size, -1])
    Lab = np.zeros([row, col, 3])
    Lab[:,:,0] = rgb2lab(io.imread(image_content))[:,:,0]
    for x in range(edge_size, row-edge_size):
        for y in range(edge_size, col-edge_size):
            Lab[x, y, 1] = ab[x-edge_size, y-edge_size, 0]
            Lab[x, y, 2] = ab[x-edge_size, y-edge_size, 1]
    return Lab

# cell 7 输出图像
output = lab2rgb(rebuild(image_content))
io.imshow(output)